// Copyright (C) 2012 by Johann Duscher <jonny.dee@gmx.net>, Kentaro Fukuchi <kentaro@fukuchi.org>
//
// This file is part of barcodeart-pp.
//
// barcodeart-pp is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// barcodeart-pp is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with barcodeart-pp. If not, see <http://www.gnu.org/licenses/>.

#include <cassert>

#include <barcodeart/IBarCode.hpp>

#include "barcodeart/ansiwriter/ANSIWriter.hpp"
#include "barcodeart/ansiwriter/ANSIWriterConfig.hpp"


namespace barcodeart
{

namespace ansiwriter
{

ANSIWriter::ANSIWriter()
{
}

int ANSIWriter::write(std::ostream& out, const IBarCode& barCode, const IWriterConfig& iConfig) const
{
    const ANSIWriterConfig& config = dynamic_cast<const ANSIWriterConfig&>(iConfig);

    /* data */
    for(int y = 0; y < barCode.getHeight(); y++)
    {
        bool last = false;
        writeWhite(out, config);

        for(int x = 0; x < barCode.getWidth(); x++)
        {
            if(barCode.isBlack(y, x))
            {
                if (!last)
                {
                    writeBlack(out, config);
                    last = true;
                }
            }
            else
            {
                if (last)
                {
                    writeWhite(out, config);
                    last = false;
                }
            }

            out << "  ";
        }

        out << "\033[0m\n";
    }

    return 0;
}

int ANSIWriter::writeBlack(std::ostream& out, const ANSIWriterConfig& config) const
{
    switch (config.getType())
    {
    case ANSIWriterConfig::NORMAL:
        out << "\033[40m";
        return 5;
    case ANSIWriterConfig::ANSI256:
        /* codes for 256 color compatible terminals */
        out << "\033[48;5;16m";
        return 10;
    }
    return -1;
}

int ANSIWriter::writeWhite(std::ostream& out, const ANSIWriterConfig& config) const
{
    switch (config.getType())
    {
    case ANSIWriterConfig::NORMAL:
        out << "\033[47m";
        return 5;
    case ANSIWriterConfig::ANSI256:
        /* codes for 256 color compatible terminals */
        out << "\033[48;5;231m";
        return 11;
    }
    return -1;
}

}

}
